package demo.DtoToVo;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;

/**
 * @author : GuoFei
 * @date : 2019/4/26 15:58
 */
public class TransVO {

    public static <T, E> void transalte(T t, E e) {
        Method[] tms = t.getClass().getDeclaredMethods();
        Method[] tes = e.getClass().getDeclaredMethods();
        for (Method m1 : tms) {
            if (m1.getName().startsWith("get")) {
                String mNameSubfix = m1.getName().substring(3);
                String forName = "set" + mNameSubfix;
                for (Method m2 : tes) {
                    if (m2.getName().equals(forName)) {
                        boolean canContinue = m2.getParameterTypes()[0].isAssignableFrom(m1.getReturnType());
                        if (canContinue) {
                            try {
                                m2.invoke(e, m1.invoke(t));
                                break;
                            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
                                e1.printStackTrace();
                            }
                        } else {
                            Class[] params = m2.getParameterTypes();
                            try {
                                Field listField = t.getClass().getDeclaredField(lowwerFirstWord(mNameSubfix));
                                ParameterizedType type = (ParameterizedType) listField.getGenericType();
                                if (params[0].newInstance() instanceof Collection) {
                                    Collection list = getList(params[0],type.getActualTypeArguments()[0].getClass(), (Collection) m1.invoke(t));
                                    m2.invoke(e, list);
                                }
                            } catch (Exception e1) {
                                e1.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    private static <T> Collection<T> getList(Class c , Class<T> tClass, Collection t) {
        Collection<T> arrayList = null;
        try {
            arrayList = (Collection<T>) c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        Collection<T> finalArrayList = arrayList;
        t.forEach(s -> finalArrayList.add((T)s));
        return finalArrayList;
    }

    private static String lowwerFirstWord(String word) {
        String w = word.substring(0, 1);
        String res = w.toLowerCase() + word.substring(1);
        return res;
    }

}
